// 函数声明（Function Declaration）
function sum(x, y) {
	return x + y;
}

// 函数表达式（Function Expression）
let mySum = function (x, y) {
	return x + y;
};



//一个函数有输入和输出，要在 TypeScript 中对其进行约束，需要把输入和输出都考虑到，其中函数声明的类型定义较简单：
function sum(x: number, y: number): number{
	return x + y;
}
//注意，输入多余的（或者少于要求的）参数，是不被允许的：



//函数表达式
let mySum: (X: number, y: number) => number = function(x: number, y: number): number{
	return x + y;
}
//在 TypeScript 的类型定义中，=> 用来表示函数的定义，左边是输入类型，需要用括号括起来，右边是输出类型。


//用接口定义函数的形状
interface SearchFunc{
	(source: string, subString: string): boolean
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string){
	return source.search(subString) !== -1;
}


//可选参数
function buildName(firstName: string, lastName?: string){
	if(lastName){
		return firstName + ' ' + lastName;
	}else{
		return firstName;
	}
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');
//需要注意的是，可选参数必须接在必需参数后面。换句话说，可选参数后面不允许再出现必须参数了：




//参数默认值
//TypeScript 会将添加了默认值的参数识别为可选参数：
function buildName(firstName: string, lastName: string = 'Cat'){
	return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');
//此时就不受「可选参数必须接在必需参数后面」的限制了：


//剩余参数
//items 是一个数组。所以我们可以用数组的类型来定义它：
function push(array: any[], ...items: any[]){
	items.forEach(function(item){
		array.push(item);
	})
}
let a = [];
push(a, 1, 2, 3);



//重载
//重载允许一个函数接受不同数量或类型的参数时，作出不同的处理
function reverse(x:number | string): number | string{
	if(typeof x === 'number'){
		return Number(x.toString().split('').reverse().join(''));
	}else if(typeof x === 'string'){
		return x.split('').reverse().join('');
	}
}
//然而这样有一个缺点，就是不能够精确的表达，输入为数字的时候，输出也应该为数字，输入为字符串的时候，输出也应该为字符串。
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}
//上例中，我们重复定义了多次函数 reverse，前几次都是函数定义，最后一次是函数实现























